import random
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec


class Base:
    def __init__(self, browser, url):
        """
        选择浏览器并打开然后最大化,并输入网址
        """
        # 添加浏览器启动配置,不自动杀掉进程
        option1 = webdriver.ChromeOptions()
        option1.add_experimental_option("detach", True)
        option1.add_experimental_option('w3c', False)
        if browser == "C" or browser == "Chrome":
            self.driver = webdriver.Chrome(chrome_options=option1)
        elif browser == "F" or browser == "Firefox":
            self.driver = webdriver.Firefox()
        else:
            raise NameError("请输入正确的浏览器参数！！！")
        # 最大化浏览器窗口
        self.driver.maximize_window()
        # 输入网址
        self.driver.get(url)
        sleep(1)

    def _location_element(self, location, value, num="dan"):
        """
        定位元素
        :param location:定位方法
        :param value: 定位方法所对应的值
        :param num: 当num="dan" ,返回的是单个元素定位，其他值，为复数
        :return: 定位到的元素
        """
        if location == "id":
            locator = (By.ID, value)
        elif location == "name":
            locator = (By.NAME, value)
        elif location == "cn":
            locator = (By.CLASS_NAME, value)
        elif location == "xp":
            locator = (By.XPATH, value)
        elif location == "tn":
            locator = (By.TAG_NAME, value)
        elif location == "lt":
            locator = (By.LINK_TEXT, value)
        elif location == "plt":
            locator = (By.PARTIAL_LINK_TEXT, value)
        elif location == "css":
            locator = (By.CSS_SELECTOR, value)
        else:
            raise NameError("请输入正确的定位方式！！！")
        if num == "dan":
            # return self.driver.find_element(*locator)  # *表示解包元组
            return WebDriverWait(self.driver, 5, 1).until(ec.presence_of_element_located(locator))
        else:
            # return self.driver.find_elements(*locator)
            return WebDriverWait(self.driver, 5, 1).until(ec.presence_of_all_elements_located(locator))

    def send_keys(self, location, value, text):
        """
        对定位到的元素输入内容
        :param location: 定位的方法
        :param value: 定位方法所对应的值
        :param text: 需要输入的文本
        :return:
        """
        ele = self._location_element(location, value)
        ele.send_keys(Keys.CONTROL, 'a')
        ele.send_keys(Keys.BACKSPACE)
        ele.send_keys(text)

    def click(self, location, value):
        """
        对定位到的元素进行点击
        :param location: 定位方法
        :param value: 定位方法所对应的值
        :return:
        """
        self._location_element(location, value).click()

    def locate(self, location, value):
        """
        定位元素
        :param location: 定位方法
        :param value: 定位方法所对应的值
        :return:
        """
        self._location_element(location, value)

    def switch_to_frame(self, location, value):
        """
        进入iframe框架
        :param location:定位方法
        :param value: 定位方法所对应的值
        :return:
        """
        ele = self._location_element(location, value)
        self.driver.switch_to.frame(ele)

    def switch_to_default_content(self):
        """
        退出到iframe框架最外层
        :return:
        """
        self.driver.switch_to.default_content()

    def switch_to_parent_frame(self):
        """
        退出到iframe框架上一层
        :return:
        """
        self.driver.switch_to.parent_frame()

    def select_by_index(self, location, value, num):
        """
        select下拉框，通过索引定位
        :param location: 定位方法
        :param value: 定位方法所对应的值
        :param num: 索引
        :return:
        """
        ele = self._location_element(location, value)
        Select(ele).select_by_index(num)

    def select_by_value(self, location, value, value1):
        """
        select下拉框，通过value定位
        :param location: 定位方法
        :param value: 定位方法所对应的值
        :param value1: value值
        :return:
        """
        ele = self._location_element(location, value)
        Select(ele).select_by_value(value1)

    def select_by_visible_text(self, location, value, text):
        """
        select下拉框，通过文本定位
        :param location: 定位方法
        :param value: 定位方法所对应的值
        :param text: 文本值
        :return:
        """
        ele = self._location_element(location, value)
        Select(ele).select_by_visible_text(text)

    def twice_element(self, location1, value1, location2, value2):
        """
        二次定位，可以实现对元素集合进行随机点击
        :param by1: 父级的定位方法
        :param value1: 父级的定位方法所对应的值
        :param by2: 子级的定位方法
        :param value2: 子级的定位方法所对应的值
        :return:
        """
        ele = self._location_element(location1, value1)._location_element(location2, value2)
        random.choice(ele).click()

    def get_text(self, location, value):
        """
        获取单个文本
        :param location: 定位方法
        :param value: 定位方法所对应的值
        :return: 获取到的文本
        """
        return self._location_element(location, value).text

    def get_texts(self, location, value):
        """
        获取多个文本
        :param location: 定位方法
        :param value: 定位方法所对应的值
        :return:
        """
        eles = self._location_element(location, value, num="shuang")
        texts = []
        for ele in eles:
            text = ele.text
            texts.append(text)
        return texts

    def save_screenshot(self, filename):
        """
        保存截图，格式是png
        :param filename: 截图保存的路径
        :return:
        """
        self.driver.save_screenshot(filename)

    def get_screenshot_as_file(self, filename):
        """
        保存截图，格式是png
        :param filename: 截图保存的路径
        :return:
        """
        self.driver.get_screenshot_as_file(filename)

    def quit(self):
        """
        杀浏览器进程
        :return:
        """
        self.driver.quit()